package xyz.xtt.pay.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import cn.hutool.json.JSONUtil;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.api.enums.RocketMessageDelayLevelEnum;
import xyz.xtt.pay.api.dto.BusinessOrderStatusChangeMsg;
import xyz.xtt.pay.api.enums.PayOrderBusinessTypeEnum;
import xyz.xtt.pay.api.enums.PayOrderStatusEnum;
import xyz.xtt.pay.client.response.TblPayOrderDto;
import xyz.xtt.pay.dto.OrderRefundMessage;
import xyz.xtt.pay.entity.TblPayOrder;
import xyz.xtt.pay.service.IRocketMqService;
import xyz.xtt.pay.service.ITblPayOrderService;

/**
 * @author huqibo
 * @date 2024/11/15
 */
@Slf4j
@Service
@RefreshScope
public class RocketMqServiceImpl implements IRocketMqService {

	@Autowired
	private RocketMQTemplate rocketMQTemplate;
	@Autowired
	private ITblPayOrderService payOrderService;

	@Value("${rocketmq.producer.syncack}")
	private String nftLandSyncAck;

	@Value("${asset.sync.pagesize:100}")
	private Integer assetSyncePageSize;

	@Value("${rocketmq.order.refund.topic}")
	private String orderRefundTopic;

	@Value("${rocketmq.pay.order.status.change.topic:nft_pay_order_status_change}")
	private String payOrderStatusChangeTopic;

	@Value("${rocketmq.business.order.status.change.topic:nft_pay_business_order_status_change_topic}")
	private String businessOrderStatusChangeTopic;

	/**
	 * 发送支付订单状态变更消息
	 *
	 * @param payOrderId 支付订单id
	 */
	@Override
	public void sendPayOrderStatusChangeMsg(long payOrderId) {
		TblPayOrder payOrder = payOrderService.getById(payOrderId);
		TblPayOrderDto payOrderDto = new TblPayOrderDto();
		BeanUtils.copyProperties(payOrder, payOrderDto);
		String tag = calPayOrderStatusChangeTag(payOrderDto);
		String topic = String.format("%s:%s", payOrderStatusChangeTopic, tag);
		String message = JSONUtil.toJsonStr(payOrderDto);
		log.info("sendPayOrderStatusChangeMsg topic:{} message:{}", topic, message);
		SendResult sendResult = rocketMQTemplate.syncSend(topic, message);
		log.info("sendPayOrderStatusChangeMsg topic:{} sendResult:{}", nftLandSyncAck, JSONUtil.toJsonStr(sendResult));
	}

	/**
	 * 根据支付单类型和状态计算tag
	 * 
	 * @param payOrderDto
	 * @return
	 */
	private String calPayOrderStatusChangeTag(TblPayOrderDto payOrderDto) {
		return String
				.format("%s:%s", PayOrderBusinessTypeEnum.getByCode(payOrderDto.getBusinessType()).name(), PayOrderStatusEnum
						.getByCode(payOrderDto.getPayStatus())
						.name());
	}

	@Override
	public void sendOrderRefundMsg(@Positive long orderId, @NotNull String buyerUserId) {
		OrderRefundMessage messageObj = OrderRefundMessage.builder().orderId(orderId).buyerUserId(buyerUserId).build();
		String message = JSONUtil.toJsonStr(messageObj);
		SendResult sendResult = rocketMQTemplate.syncSend(orderRefundTopic, message);
		log.info("sendAssetTransactionRefundMsg topic:{} msg:{} sendResult:{}", orderRefundTopic, message, JSONUtil.toJsonStr(sendResult));
	}

	@Override
	public void sendDelayedMessage(String topic, String tag, String message, RocketMessageDelayLevelEnum delayLevel) {
		if (StringUtils.isNotBlank(tag)) {
			topic = String.format("%s:%s", topic, tag);
		}
		SendResult sendResult = rocketMQTemplate.syncSend(topic, MessageBuilder.withPayload(message).build(), 2000, delayLevel.level());
		log.info("sendDelayedMessage topic:{} sendResult:{}", topic, JSONUtil.toJsonStr(sendResult));
	}

	/**
	 * 发送业务订单支付状态变更消息
	 *
	 * @param businessOrderId  业务订单id
	 * @param businessTypeEnum
	 * @param payStatus
	 */
	@Override
	public void sendBusinessOrderStatusChangeMsg(Long businessOrderId, PayOrderBusinessTypeEnum businessTypeEnum, PayOrderStatusEnum payStatus) {
		String tag = String.format("%s_%s", businessTypeEnum.name().toLowerCase(), payStatus.name().toLowerCase());
		String topic = String.format("%s:%s", businessOrderStatusChangeTopic, tag);
		BusinessOrderStatusChangeMsg businessOrderStatusChangeMsg = new BusinessOrderStatusChangeMsg();
		businessOrderStatusChangeMsg.setBusinessOrderId(businessOrderId);
		businessOrderStatusChangeMsg.setOrderStatus(payStatus.getCode());
		String message = JSONUtil.toJsonStr(businessOrderStatusChangeMsg);
		log.info("sendBusinessOrderStatusChangeMsg topic:{} message:{}", topic, message);
		SendResult sendResult = rocketMQTemplate.syncSend(topic, message);
		log.info("sendBusinessOrderStatusChangeMsg topic:{} sendResult:{}", topic, JSONUtil.toJsonStr(sendResult));
	}
}
